/**
 * @file ExperiInit.h
 * @author
 * @brief 试验数据初始化类
 * @version 0.1
 * @date 2022-07-15
 *
 * @copyright Copyright (c)
 *
 */

#ifndef CEXPERIINIT_H
#define CEXPERIINIT_H
#include <string>
#include "json/json.h"
#include "stdafx.h"

#include <tao/ORB_Core.h>
#include <tao/Object.h>
#include <tao/Invocation_Adapter.h>
#include <orbsvcs/CosNamingC.h> //morp

using namespace std;

/**
 * @brief 试验数据初始化类
 *
 * @details
 */
class CExperiInit {
public:
	/**
	 * @brief 构造函数
	 *
	 * @details
	 */
	CExperiInit();
	/**
	 * @brief 析构函数
	 *
	 * @details
	 */
	~CExperiInit();

public:
	/**
	 * @brief 初始化CExperiInit实例.
	 * @param [in] argc 命令行参数argc
	 * @param [in] argv 命令行参数argv
	 * @return true 成功
	 * @return false 失败
	 *
	 * @details 1、初始化CORBO。 2、设置默认工作目录。
	 */
	bool initHandler(int argc, char* argv[]);
	/**
	 * @brief 设置工作目录
	 * @param [in] strDir 目录
	 *
	 * @details
	 */
	void setWorkDir(const std::string& strDir);
	/**
	 * @brief CExperiInit的当前工作目录
	 * @return std::string 当前工作目录
	 *
	 * @details
	 */
	std::string workDir() const;
	/**
	 * @brief CExperiInit当前的试验样本文件全路径
	 * @return std::string 试验样本文件全路径
	 *
	 * @details
	 */
	std::string currentExperiFile() const;
	/**
	 * @brief 调用app的初始化方法.
	 * @param [in] strServantName vom在中间件的注册标识. 构成：包名::类名::app名
	 * @param [in] strTaoOpertion 初始化方法名称
	 * @param [in] strType 参数类型
	 * @param [in] pszValue 参数
	 * @return Json::Value 调用结果. 格式：{"state":0, "name":"setLength", "message":"ok"}
	 *
	 * @details
	 */
	Json::Value callInitMethod(const std::string& strServantName, const std::string& strTaoOpertion,
	                           const std::string& strType, const char* pszValue);
	/**
	 * @brief 执行下载并.
	 * @param [in] downloadXml
	 * @return std::string  返回结果文件全路径
	 *
	 * @details data对象格式:{"cmd": 2001, "url": "http://192.168.1.1/download/file.xml"}
	 */
	std::string download(const std::string downloadXml);
	/**
	 * @brief 获取rpc响应的返回码
	 * @param [in] retObj json对象格式返回
	 * @param [in] failMsg rpc 错误信息
	 * @return int
	 *
	 * @details
	 */
	int getRpcRetValueFromJson(Json::Value& retObj, std::string& failMsg);

private:
	/**
	 * @brief 释放申请的内存.
	 *
	 * @details
	 */
	void releaseTaoArgs(void);
	/**
	 * @brief 执行初始化方法
	 * @param [in] strServantName 模型实例id
	 * @param [in] strTaoOpertion 初始化方法函数名
	 * @param [in] strType 初始化方法函数参数的类型
	 * @param [in] nTaoArgsCount 函数签名中除函数名之外的 返回值个数  参数个数的总和
	 * @param [in] nVectorIdx vector的index,从0开始
	 * @param [in] pszValue  vector[index]
	 * @return Json::Value
	 *
	 * @details  初始化方法函数名  void set_function(int value)  or void set_function(int index, int value)
	 *  当  nTaoArgsCount = 2 时, nVectorIdx = 0, pszValue = vector[index]
	 *  当  nTaoArgsCount = 3 时, nVectorIdx = index, pszValue = vector[index]
	 */
	Json::Value CExperiInit::executeRpc(const std::string& strServantName, const std::string& strTaoOpertion,
	                                    const std::string& strType, int nTaoArgsCount, int nVectorIdx,
	                                    const char* pszValue);
	/**
	 * @brief 提取字符串 形如 "vector<int>"中的类型.
	 * @param [in] strType 字符串 必须是 "vector<类型>"
	 * @return std::string  若含有vector,则返回类型，否则为空
	 *
	 * @details 函数内部对strType 做了去空格处理
	 */
	std::string typeExtraction(const std::string& strType);
	/**
	 * @brief 将逗号组成的字符串转换为vector类型
	 * @param [in] input  逗号组成的字符串
	 * @return std::vector<string> 状态值
	 *
	 * @details 逗号组成的字符串   "1,2,3"
	 */
	std::vector<string> extractCommaSeparatedStrings(const std::string& input);

	/**
	 * @brief 拼接 模型仓库id,用于查找对象实例
	 * @param [in] strServantName
	 * @return std::string 返回值为  "IDL:package_SolidEngineState/SolidEngineState/IDL/Servant:1.0"
	 *
	 * @details
	 *  注册实例为 package_SolidEngineState::SolidEngineState::testdomain::objectid_engine
	 *  拼接id 为 包名 类名
	 */
	std::string getRepoId(const std::string& strServantName);

public:
	/**
	 * 初始化状态枚举定义.
	 */
	typedef enum _EInitState {
		Success = 0, /*!< 成功 */
		Failure = 1, /*!< 失败 */
	} EInitState;

private:
	CORBA::ORB_var m_orb; ///< CORBA对象
	CORBA::Object* m_pServant; ///< CORBA对象
	std::string m_strWorkDir; ///< 工作目录
	std::string m_strCurrExperiFile; ///< 当前样本文件全路径
	std::map<char*, int> m_stringDupMap; ///< 待释放的内存列表
};

#endif // CEXPERIINIT_H
